package com.bot.nft.module.op.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bot.common.chainbo.ChainAccountInfo;
import com.bot.common.chainbo.TradingResultsInfo;
import com.bot.common.exception.CommonException;
import com.bot.dev.api.DevBlockChainApi;
import com.bot.nft.core.config.LogDescription;
import com.bot.nft.core.enums.chain.ChainLogEnum;
import com.bot.nft.core.enums.op.SyndropEnum;
import com.bot.nft.core.util.NftCodeUtil;
import com.bot.nft.module.chain.domain.ChainOptLogInfo;
import com.bot.nft.module.chain.mapper.ChainOptLogMapper;
import com.bot.nft.module.dc.domain.DcFlowLog;
import com.bot.nft.module.dc.domain.DcNftCert;
import com.bot.nft.module.dc.domain.DcNftInfo;
import com.bot.nft.module.dc.domain.vo.DcNftCertVo;
import com.bot.nft.module.dc.domain.vo.DcNftInfoVo;
import com.bot.nft.module.dc.mapper.DcFlowLogMapper;
import com.bot.nft.module.dc.mapper.DcNftCertMapper;
import com.bot.nft.module.dc.mapper.DcNftInfoMapper;
import com.bot.nft.module.mb.domain.MbUserInfo;
import com.bot.nft.module.mb.mapper.IMbMemberMapper;
import com.bot.nft.module.op.domain.*;
import com.bot.nft.module.op.domain.bo.*;
import com.bot.nft.module.op.domain.vo.*;
import com.bot.nft.module.op.mapper.*;
import com.bot.nft.module.op.service.ISynService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class SynServiceImpl implements ISynService {

    @Resource
    private OpSynActInfoMapper opSynActInfoMapper;

    @Resource
    private OpSynActRulesMapper opSynActRulesMapper;

    @Resource
    private OpSynDoorsRelMapper opSynDoorsRelMapper;

    @Resource
    private OpSynDoorsRulesMapper opSynDoorsRulesMapper;

    @Resource
    private OpSynMaterMapper opSynMaterMapper;

    @Resource
    private OpSynRecordLogMapper opSynRecordLogMapper;

    @Resource
    private DcNftInfoMapper dcNftInfoMapper;

    @Resource
    private DcNftCertMapper dcNftCertMapper;

    @Resource
    private DcFlowLogMapper dcFlowLogMapper;

    @Resource
    private DevBlockChainApi devBlockChainApi;

    @Resource
    private IMbMemberMapper iMbMemberMapper;


    @Resource
    private ChainOptLogMapper chainOptLogMapper;


    /**
     * 添加合成活动
     *
     * @param opSynActInfoBo 合成活动信息
     * @return
     */
    @Override
    public Boolean addSyn(OpSynActInfoBo opSynActInfoBo) {
        Boolean flag;
        Date startTime = opSynActInfoBo.getStartTime();
        Date endTime = opSynActInfoBo.getEndTime();
        if (startTime.getTime() < endTime.getTime()) {
            //合成信息id
            String synActId = IdUtil.getSnowflakeNextIdStr();
            opSynActInfoBo.setId(synActId);
            //添加合成基本信息
            OpSynActInfo opSynActInfo = BeanUtil.toBean(opSynActInfoBo, OpSynActInfo.class);
            int insert = opSynActInfoMapper.insert(opSynActInfo);
            if (insert > 0) {
                flag = true;
            }
            //添加合成藏品规则条件项信息
            List<OpSynActRulesBo> opSynActRulesBos = opSynActInfoBo.getOpSynActRulesBos();
            String nftId = "";
            for (OpSynActRulesBo opSynActRulesBo : opSynActRulesBos) {
                //藏品规则条件项id
                String ruiesId = IdUtil.getSnowflakeNextIdStr();
                opSynActRulesBo.setId(ruiesId);
                opSynActRulesBo.setSynActId(synActId);
                //nftid判重
                if (opSynActRulesBo.getNftId().equals(nftId)) {
                    //条件构造器
                    QueryWrapper<DcNftInfo> wrapper = new QueryWrapper<>();
                    LambdaQueryWrapper<DcNftInfo> lambda = wrapper.lambda();
                    lambda.eq(DcNftInfo::getId, nftId);
                    String name = dcNftInfoMapper.selectOne(wrapper).getName();
                    ;
                    throw new CommonException("合成后藏品：" + name + "重复，请重新设置");
                }
                nftId = opSynActRulesBo.getNftId();

                Boolean flagStock = checkStockAdd(opSynActRulesBo.getNftId(), opSynActRulesBo.getInventory());
                if (!flagStock) {
                    //条件构造器
                    QueryWrapper<DcNftInfo> wrapper = new QueryWrapper<>();
                    LambdaQueryWrapper<DcNftInfo> lambda = wrapper.lambda();
                    lambda.eq(DcNftInfo::getId, nftId);
                    String ntfName = dcNftInfoMapper.selectOne(wrapper).getName();
                    throw new CommonException("合成后藏品：" + ntfName + "，库存不足，请重新设置");
                }
            }
            List<OpSynActRules> opSynActRules = BeanUtil.copyToList(opSynActRulesBos, OpSynActRules.class);
            flag = opSynActRulesMapper.insertBatch(opSynActRules);
            //添加原材料信息
            List<OpSynMaterBo> opSynMaterBos = opSynActInfoBo.getOpSynMaterBos();
            for (OpSynMaterBo opSynMaterBo : opSynMaterBos) {
                //合成原材料信息id
                String SynRawMatInfostr = IdUtil.getSnowflakeNextIdStr();
                opSynMaterBo.setId(SynRawMatInfostr);
                opSynMaterBo.setSynActId(synActId);
            }
            List<OpSynMater> opSynMaters = BeanUtil.copyToList(opSynMaterBos, OpSynMater.class);
            flag = opSynMaterMapper.insertBatch(opSynMaters);
            //添加门槛信息
            List<OpSynDoorsRelBo> opSynDoorsRelBos = opSynActInfoBo.getOpSynDoorsRelBos();
            if (opSynDoorsRelBos.size() > 0) {
                for (OpSynDoorsRelBo opSynDoorsRelBo : opSynDoorsRelBos) {
                    //门槛信息id
                    String doorId = IdUtil.getSnowflakeNextIdStr();
                    opSynDoorsRelBo.setId(doorId);
                    opSynDoorsRelBo.setSynActId(synActId);
                }
                List<OpSynDoorsRel> opSynDoorsRels = BeanUtil.copyToList(opSynDoorsRelBos, OpSynDoorsRel.class);
                flag = opSynDoorsRelMapper.insertBatch(opSynDoorsRels);
                //添加门槛具体信息
                for (int i = 0; i < opSynDoorsRelBos.size(); i++) {
                    String id = opSynDoorsRelBos.get(i).getId();
                    List<OpSynDoorsRulesBo> opSynDoorsRulesBos = opSynDoorsRelBos.get(i).getOpSynDoorsRulesBos();
                    for (OpSynDoorsRulesBo opSynDoorsRulesBo : opSynDoorsRulesBos) {
                        //门槛具体信息id
                        String doorsId = IdUtil.getSnowflakeNextIdStr();
                        opSynDoorsRulesBo.setId(doorsId);
                        opSynDoorsRulesBo.setDoorsId(id);
                    }
                    List<OpSynDoorsRules> opSynDoorsRules = BeanUtil.copyToList(opSynDoorsRulesBos, OpSynDoorsRules.class);
                    flag = opSynDoorsRulesMapper.insertBatch(opSynDoorsRules);
                }
            }
        } else {
            throw new CommonException("结束时间不能比开始时间早");
        }
        return flag;
    }

    /**
     * 修改合成活动信息
     *
     * @param opSynActInfoBo 合成活动信息
     * @return
     */
    @Override
    public Boolean updateSyn(OpSynActInfoBo opSynActInfoBo) {
        Boolean flag;
        Date startTime = opSynActInfoBo.getStartTime();
        Date endTime = opSynActInfoBo.getEndTime();
        if (startTime.getTime() < endTime.getTime()) {
            //合成信息id
            String id = opSynActInfoBo.getId();
            //条件构造器
            UpdateWrapper<OpSynActInfo> wrapper = new UpdateWrapper<>();
            // 设置更新条件：根据用户ID查找记录
            wrapper.eq("id", id);
            //修改合成基本信息
            OpSynActInfo opSynActInfo = BeanUtil.toBean(opSynActInfoBo, OpSynActInfo.class);
            int insert = opSynActInfoMapper.update(opSynActInfo, wrapper);
            if (insert > 0) {
                flag = true;
            }
            //删除规则项信息
            QueryWrapper<OpSynActRules> opSynWrapper = new QueryWrapper<>();
            opSynWrapper.lambda().eq(OpSynActRules::getSynActId, id);
            opSynActRulesMapper.delete(opSynWrapper);
            //删除原材料信息
            QueryWrapper<OpSynMater> opSynMater = new QueryWrapper<>();
            opSynMater.lambda().eq(OpSynMater::getSynActId, id);
            opSynMaterMapper.delete(opSynMater);
            //查看门槛信息
            QueryWrapper<OpSynDoorsRel> opSynDoorsRelQueryWrapper = new QueryWrapper<>();
            opSynDoorsRelQueryWrapper.lambda().eq(OpSynDoorsRel::getSynActId, id);
            List<OpSynDoorsRelVo> opSynDoorsRelVos = opSynDoorsRelMapper.selectVoList(opSynDoorsRelQueryWrapper);
            for (OpSynDoorsRelVo opSynDoorsRelVo : opSynDoorsRelVos) {
                String doorId = opSynDoorsRelVo.getId();
                //查看门槛具体信息
                QueryWrapper<OpSynDoorsRules> opSynDoorsRulesQueryWrapper = new QueryWrapper<>();
                opSynDoorsRulesQueryWrapper.lambda().eq(OpSynDoorsRules::getDoorsId, doorId);
                opSynDoorsRulesMapper.delete(opSynDoorsRulesQueryWrapper);
            }
            //删除门槛信息
            QueryWrapper<OpSynDoorsRel> opSynDoorsRelQuery = new QueryWrapper<>();
            opSynDoorsRelQuery.lambda().eq(OpSynDoorsRel::getSynActId, id);
            opSynDoorsRelMapper.delete(opSynDoorsRelQuery);
            //添加合成藏品规则条件项信息
            List<OpSynActRulesBo> opSynActRulesBos = opSynActInfoBo.getOpSynActRulesBos();
            String nftId = "";
            for (OpSynActRulesBo opSynActRulesBo : opSynActRulesBos) {
                //藏品规则条件项id
                String ruiesId = IdUtil.getSnowflakeNextIdStr();
                opSynActRulesBo.setId(ruiesId);
                opSynActRulesBo.setSynActId(id);
                //nftid判重
                if (opSynActRulesBo.getNftId().equals(nftId)) {
                    //条件构造器
                    QueryWrapper<DcNftInfo> dcNftInfoQueryWrapper = new QueryWrapper<>();
                    LambdaQueryWrapper<DcNftInfo> lambda = dcNftInfoQueryWrapper.lambda();
                    lambda.eq(DcNftInfo::getId, nftId);
                    String name = dcNftInfoMapper.selectOne(dcNftInfoQueryWrapper).getName();
                    ;
                    throw new CommonException("合成后藏品：" + name + "重复，请重新设置");
                }
                nftId = opSynActRulesBo.getNftId();

                Boolean flagStock = checkStockAdd(opSynActRulesBo.getNftId(), opSynActRulesBo.getInventory());
                if (!flagStock) {
                    //条件构造器
                    QueryWrapper<DcNftInfo> dcNftInfoQueryWrapper = new QueryWrapper<>();
                    LambdaQueryWrapper<DcNftInfo> lambda = dcNftInfoQueryWrapper.lambda();
                    lambda.eq(DcNftInfo::getId, nftId);
                    String ntfName = dcNftInfoMapper.selectOne(dcNftInfoQueryWrapper).getName();
                    throw new CommonException("合成后藏品：" + ntfName + "，库存不足，请重新设置");
                }
            }
            List<OpSynActRules> opSynActRules = BeanUtil.copyToList(opSynActRulesBos, OpSynActRules.class);
            flag = opSynActRulesMapper.insertBatch(opSynActRules);
            //添加原材料信息
            List<OpSynMaterBo> opSynMaterBos = opSynActInfoBo.getOpSynMaterBos();
            for (OpSynMaterBo opSynMaterBo : opSynMaterBos) {
                //合成原材料信息id
                String SynRawMatInfostr = IdUtil.getSnowflakeNextIdStr();
                opSynMaterBo.setId(SynRawMatInfostr);
                opSynMaterBo.setSynActId(id);
            }
            List<OpSynMater> opSynMaters = BeanUtil.copyToList(opSynMaterBos, OpSynMater.class);
            flag = opSynMaterMapper.insertBatch(opSynMaters);
            //添加门槛信息
            List<OpSynDoorsRelBo> opSynDoorsRelBos = opSynActInfoBo.getOpSynDoorsRelBos();
            for (OpSynDoorsRelBo opSynDoorsRelBo : opSynDoorsRelBos) {
                //门槛信息id
                String doorId = IdUtil.getSnowflakeNextIdStr();
                opSynDoorsRelBo.setId(doorId);
                opSynDoorsRelBo.setSynActId(id);
            }
            List<OpSynDoorsRel> opSynDoorsRels = BeanUtil.copyToList(opSynDoorsRelBos, OpSynDoorsRel.class);
            flag = opSynDoorsRelMapper.insertBatch(opSynDoorsRels);
            //添加门槛具体信息
            for (int i = 0; i < opSynDoorsRelBos.size(); i++) {
                String doorId = opSynDoorsRelBos.get(i).getId();
                List<OpSynDoorsRulesBo> opSynDoorsRulesBos = opSynDoorsRelBos.get(i).getOpSynDoorsRulesBos();
                for (OpSynDoorsRulesBo opSynDoorsRulesBo : opSynDoorsRulesBos) {
                    //门槛具体信息id
                    String doorsId = IdUtil.getSnowflakeNextIdStr();
                    opSynDoorsRulesBo.setId(doorsId);
                    opSynDoorsRulesBo.setDoorsId(doorId);
                }
                List<OpSynDoorsRules> opSynDoorsRules = BeanUtil.copyToList(opSynDoorsRulesBos, OpSynDoorsRules.class);
                flag = opSynDoorsRulesMapper.insertBatch(opSynDoorsRules);
            }
        } else {
            throw new CommonException("结束时间不能比开始时间早");
        }
        return flag;
    }

    /**
     * 删除合成活动
     *
     * @param id 合成活动标识
     * @return
     */
    @Override
    public Boolean delSyn(String id) {
        //条件构造器
        LambdaUpdateWrapper<OpSynActInfo> wrapper = new LambdaUpdateWrapper<>();
        // 设置更新条件：根据用户ID查找记录
        wrapper.eq(OpSynActInfo::getId, id);
        // 设置要更新的字段和新值：例如更新用户状态
        wrapper.set(OpSynActInfo::getDeleteFlag, SyndropEnum.DELETE.getValue());
        int i = opSynActInfoMapper.update(null, wrapper);
        return i > 0;
    }

    /**
     * 启用合成活动
     *
     * @param id 合成活动标识
     * @return
     */
    @Override
    public Boolean enableSyn(String id) {
        Boolean flag;
        //条件构造器
        LambdaUpdateWrapper<OpSynActInfo> updateWrapper = new LambdaUpdateWrapper<>();
        // 设置更新条件：根据用户ID查找记录
        updateWrapper.eq(OpSynActInfo::getId, id);
        // 设置要更新的字段和新值：例如更新用户状态
        updateWrapper.set(OpSynActInfo::getStatus, SyndropEnum.ENABLE_STATUS.getValue());
        // 执行更新操作
        int rowsAffected = opSynActInfoMapper.update(null, updateWrapper);
        if (rowsAffected > 0) {
            flag = true;
        } else {
            flag = false;
        }
        return flag;
    }

    /**
     * 禁用合成活动
     *
     * @param id 合成活动标识
     * @return
     */
    @Override
    public Boolean disableSyn(String id) {
        Boolean flag;
        //条件构造器
        LambdaUpdateWrapper<OpSynActInfo> updateWrapper = new LambdaUpdateWrapper<>();
        // 设置更新条件：根据用户ID查找记录
        updateWrapper.eq(OpSynActInfo::getId, id);
        // 设置要更新的字段和新值：例如更新用户状态
        updateWrapper.set(OpSynActInfo::getStatus, SyndropEnum.DISABLE_STATUS.getValue());
        // 执行更新操作
        int rowsAffected = opSynActInfoMapper.update(null, updateWrapper);
        if (rowsAffected > 0) {
            flag = true;
        } else {
            flag = false;
        }
        return flag;
    }

    /**
     * 查看合成活动
     *
     * @param id 合成活动标识
     * @return
     */
    @Override
    public OpSynActInfoVo getSyn(String id) {
        OpSynActInfoVo opSynActInfoVo;
//        //条件构造器
//        QueryWrapper<OpSynActInfo> wrapper = new QueryWrapper<>();
//        wrapper.lambda().eq(OpSynActInfo::getId,id);
        opSynActInfoVo = opSynActInfoMapper.selectVoById(id);
        //查看合成藏品规则信息
        List<OpSynActRulesVo> opSynActRulesVos = opSynActRulesMapper.getActRules(id);
        opSynActInfoVo.setOpSynActRulesVos(opSynActRulesVos);
        //查看原材料信息
        List<OpSynMaterVo> opSynMaterVos = opSynMaterMapper.getMater(id);
        opSynActInfoVo.setOpSynMaterVos(opSynMaterVos);
        //查看门槛信息
        QueryWrapper<OpSynDoorsRel> opSynDoorsRelQueryWrapper = new QueryWrapper<>();
        opSynDoorsRelQueryWrapper.lambda().eq(OpSynDoorsRel::getSynActId, id);
        List<OpSynDoorsRelVo> opSynDoorsRelVos = opSynDoorsRelMapper.selectVoList(opSynDoorsRelQueryWrapper);
        for (OpSynDoorsRelVo opSynDoorsRelVo : opSynDoorsRelVos) {
            String doorId = opSynDoorsRelVo.getId();
            //查看门槛具体信息
            List<OpSynDoorsRulesVo> opSynDoorsRulesVos = opSynDoorsRulesMapper.getDoorsRules(doorId);
            opSynDoorsRelVo.setOpSynDoorsRulesVos(opSynDoorsRulesVos);
        }
        opSynActInfoVo.setOpSynDoorsRelVos(opSynDoorsRelVos);

        return opSynActInfoVo;
    }

    /**
     * 分页查询合成活动
     *
     * @param keyword  关键字
     * @param status   状态
     * @param pageNo   页码
     * @param pageSize 条数
     * @return
     */
    @Override
    public Page<OpSynActInfoVo> querySyn(String keyword, Integer status, Integer pageNo, Integer pageSize) {
        //创建分页对象
        Page<OpSynActInfoVo> synActInfoVoPage = new Page<>(pageNo, pageSize);
        //创建page分页
        Page<OpSynActInfo> page = new Page<>(pageNo, pageSize);
        //条件构造器
        QueryWrapper<OpSynActInfo> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<OpSynActInfo> lambda = wrapper.lambda();
        //分页条件
        if (StringUtils.isEmpty(keyword) || keyword != "") {
            lambda.like(OpSynActInfo::getName, keyword);
        }
        if (status != null) {
            lambda.eq(OpSynActInfo::getStatus, status);
        }
        lambda.eq(OpSynActInfo::getDeleteFlag, 0);
        //分页信息
        IPage<OpSynActInfoVo> opSynActInfoVoIPage = opSynActInfoMapper.selectVoPage(page, wrapper);
        //转换成集合
        List<OpSynActInfoVo> opSynActInfoVos = BeanUtil.copyToList(opSynActInfoVoIPage.getRecords(), OpSynActInfoVo.class);
        //循环取数据
        for (OpSynActInfoVo opSynActInfoVo : opSynActInfoVos) {
            //活动标识
            String SynId = opSynActInfoVo.getId();
            //查看合成藏品规则信息
            List<OpSynActRulesVo> opSynActRulesVos = opSynActRulesMapper.getActRules(SynId);
            //装到vo中
            opSynActInfoVo.setOpSynActRulesVos(opSynActRulesVos);
            //查看原材料信息
            List<OpSynMaterVo> opSynMaterVos = opSynMaterMapper.getMater(SynId);
            //装到vo中
            opSynActInfoVo.setOpSynMaterVos(opSynMaterVos);
            //查看门槛信息  条件构造器
            QueryWrapper<OpSynDoorsRel> opSynDoorsRelQueryWrapper = new QueryWrapper<>();
            opSynDoorsRelQueryWrapper.lambda().eq(OpSynDoorsRel::getSynActId, SynId);
            //门槛具体信息
            List<OpSynDoorsRelVo> opSynDoorsRelVos = opSynDoorsRelMapper.selectVoList(opSynDoorsRelQueryWrapper);
            for (OpSynDoorsRelVo opSynDoorsRelVo : opSynDoorsRelVos) {
                String doorId = opSynDoorsRelVo.getId();
                //查看门槛具体信息
                List<OpSynDoorsRulesVo> opSynDoorsRulesVos = opSynDoorsRulesMapper.getDoorsRules(doorId);
                //装到vo中
                opSynDoorsRelVo.setOpSynDoorsRulesVos(opSynDoorsRulesVos);
            }
            //装到vo中
            opSynActInfoVo.setOpSynDoorsRelVos(opSynDoorsRelVos);
        }
        //数据给到page中
        synActInfoVoPage.setRecords(opSynActInfoVos);
        //总共多少给到page中
        synActInfoVoPage.setTotal(opSynActInfoVoIPage.getTotal());

        return synActInfoVoPage;
    }

    /**
     * 修改库存功能
     *
     * @param synActId         当前合成藏品规则标识
     * @param opSynActRulesBos 合成藏品信息
     * @return
     */
    @Override
    public Boolean updateInven(String synActId, List<OpSynActRulesBo> opSynActRulesBos) {
        Boolean flag = null;
        for (OpSynActRulesBo opSynActRulesBo : opSynActRulesBos) {
            Boolean flagStock = checkStockUpdate(opSynActRulesBo.getNftId(), synActId, opSynActRulesBo.getInventory());
            if (!flagStock) {
                String ntfName = dcNftInfoMapper.selectVoById(opSynActRulesBo.getNftId()).getName();
                throw new CommonException("藏品：" + ntfName + "库存不足，请重新设置");
            }
            String id = opSynActRulesBo.getId();
            Integer inventory = opSynActRulesBo.getInventory();
            //条件构造器
            LambdaUpdateWrapper<OpSynActRules> updateWrapper = new LambdaUpdateWrapper<>();
            // 设置更新条件：根据用户ID查找记录
            updateWrapper.eq(OpSynActRules::getId, id).eq(OpSynActRules::getSynActId, synActId);
            // 设置要更新的字段和新值：例如更新用户状态
            updateWrapper.set(OpSynActRules::getInventory, inventory);
            int update = opSynActRulesMapper.update(null, updateWrapper);
            if (update > 0) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 合成藏品功能
     *
     * @param nftIdList 原料信息标识(证书标识)
     * @param mbId      会员标识
     * @param synId     合成活动标识
     * @return 藏品信息
     */
    @Override
    public DcNftCertVo synThesis(List<String> nftIdList, String mbId, String synId) {
        //查看合成活动信息
        OpSynActInfoVo syn = getSyn(synId);
        //活动开始时间
        Date startTime = syn.getStartTime();
        //活动结束时间
        Date endTime = syn.getEndTime();
        //当前时间
        Date date = new Date();
        //判断当前时间是否大于开始时间
        if (startTime.after(date)) {
            throw new CommonException("当前活动未开始，请稍后重试");
        } else if (endTime.before(date)) {
            throw new CommonException("当前活动已结束，请期待下次活动");
        }
        Boolean flag = null;
        DcNftCertVo certVo = null;
        //查询会员所拥有的藏品
        QueryWrapper<DcNftCert> dcNtfCertQueryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<DcNftCert> lambda = dcNtfCertQueryWrapper.lambda();
        lambda.eq(DcNftCert::getMbId, mbId);
        lambda.orderByAsc(DcNftCert::getId);
        List<DcNftCert> dcNtfCerts = dcNftCertMapper.selectList(dcNtfCertQueryWrapper);
        //查询会员所拥有的藏品id集合
        List<String> verifyBos = new ArrayList<>();
        for (int j = 0; j < dcNtfCerts.size(); j++) {
            DcNftCert dcNtfCert = dcNtfCerts.get(j);
            String id = dcNtfCert.getId();
            verifyBos.add(id);
        }
        //藏品集合
        //把会员所拥有的藏品ID循环取出来
        //放入藏品集合中
        List<String> nftIDlist = new ArrayList<>(verifyBos);
        //判断会员是否拥有原料藏品
        boolean equalList = new HashSet<>(nftIDlist).containsAll(nftIdList);
        //判断是否为ture
        if (equalList) {
            //NFT 持有者地址
            QueryWrapper<MbUserInfo> mbUserInfoQueryWrapper = new QueryWrapper<>();
            mbUserInfoQueryWrapper.lambda().eq(MbUserInfo::getId,mbId);
            MbUserInfo mbUserInfo = iMbMemberMapper.selectOne(mbUserInfoQueryWrapper);
            String owner = mbUserInfo.getNativeAddress();
            //查询门槛信息规则
            QueryWrapper<OpSynDoorsRel> opSynDoorsRelQueryWrapper = new QueryWrapper<>();
            opSynDoorsRelQueryWrapper.lambda().eq(OpSynDoorsRel::getSynActId, synId);
            List<OpSynDoorsRelVo> opSynDoorsRelVos = opSynDoorsRelMapper.selectVoList(opSynDoorsRelQueryWrapper);
            //门槛信息结果集合
            List<Boolean> equayList = new ArrayList<>();
            //发行库存量总和
            Integer inventor = 0;
            if (opSynDoorsRelVos.isEmpty()){
                //活动可合成藏品的信息
                QueryWrapper<OpSynActRules> opSynActRulesQueryWrapper = new QueryWrapper<>();
                opSynActRulesQueryWrapper.lambda().eq(OpSynActRules::getSynActId, synId);
                List<OpSynActRulesVo> opSynActRulesVos = opSynActRulesMapper.selectVoList(opSynActRulesQueryWrapper);
                //成功概率
                Integer quert = 0;
                for (OpSynActRulesVo opSynActRulesVo : opSynActRulesVos) {
                    //可合成藏品的成功概率
                    Integer probability = opSynActRulesVo.getProbability();
                    //可合成藏品的库存数量
                    Integer inventory = opSynActRulesVo.getInventory();
                    //加入发行库存量综合
                    inventor = inventor + inventory;
                    //加入成功概率
                    quert = quert + probability;
                    //该合成活动的库存量不为0
                    if (inventory != 0) {
                        //随机数
                        Random r = new Random();
                        int num = r.nextInt(100);
                        String certId = null;
                        //判断随机数和成功概率
                        if (num < quert) {
                            //可合成的库存数量减去1
                            int inven = inventory - 1;
                            String nftId = opSynActRulesVo.getNftId();
                            //修改合成后藏品的库存量
                            updSunInven(nftId,inven);

                            //藏品证书id
                            certId = IdUtil.getSnowflakeNextIdStr();
                            //添加藏品证书
                            //addDcNftCert(certId,nftId,mbId,null);

                            //添加流转记录
                            addDcFlowLog(certId,mbId);

                            //合成记录
                            addSynRecordLog(mbId,certId,synId);

                            //查看合成藏品后藏品的库存
                            updInven(nftId);

                            //修改原材料的状态和销毁藏品
                            //delNft(nftIdList,owner,mbId);

                            //发行藏品
                            //chainAcco(nftId, owner,certId,mbId);

                            //添加藏品证书
                            addDcNftCert(certId,nftId,mbId);

                            //返回藏品证书
                            certVo = dcNtfCert(certId,nftId);

                        }
                    } else {
                        //发行库存量总和是否为0
                        throw new CommonException("活动的所有藏品已经合成完");
                    }
                }
            }else {
                //循环门槛信息
                for (OpSynDoorsRelVo opSynDoorsRelVo : opSynDoorsRelVos) {
                    String doorId = opSynDoorsRelVo.getId();
                    //查看门槛具体信息
                    List<OpSynDoorsRulesVo> opSynDoorsRulesVos = opSynDoorsRulesMapper.getDoorsRules(doorId);
                    //判断会员是否符合门槛信息
                    boolean equaList = opSynDoorsRulesVos.containsAll(verifyBos);
                    //放入门槛信息结果里
                    equayList.add(equaList);
                    //判断是否为ture
                    if (equaList) {
                        //活动可合成藏品的信息
                        QueryWrapper<OpSynActRules> opSynActRulesQueryWrapper = new QueryWrapper<>();
                        opSynActRulesQueryWrapper.lambda().eq(OpSynActRules::getSynActId, synId);
                        List<OpSynActRulesVo> opSynActRulesVos = opSynActRulesMapper.selectVoList(opSynActRulesQueryWrapper);
                        //成功概率
                        Integer quert = 0;
                        for (OpSynActRulesVo opSynActRulesVo : opSynActRulesVos) {
                            //可合成藏品的成功概率
                            Integer probability = opSynActRulesVo.getProbability();
                            //可合成藏品的库存数量
                            Integer inventory = opSynActRulesVo.getInventory();
                            //加入发行库存量综合
                            inventor = inventor + inventory;
                            //加入成功概率
                            quert = quert + probability;
                            //该合成活动的库存量不为0
                            if (inventory != 0) {
                                //随机数
                                Random r = new Random();
                                int num = r.nextInt(100);
                                String certId = null;
                                //判断随机数和成功概率
                                if (num < quert) {
                                    //可合成的库存数量减去1
                                    int inven = inventory - 1;
                                    String nftId = opSynActRulesVo.getNftId();
                                    //修改合成后藏品的库存量
                                    updSunInven(nftId,inven);

                                    //藏品证书id
                                    certId = IdUtil.getSnowflakeNextIdStr();
                                    //添加藏品证书
                                    //addDcNftCert(certId,nftId,mbId,null);

                                    //添加流转记录
                                    addDcFlowLog(certId,mbId);

                                    //合成记录
                                    addSynRecordLog(mbId,certId,synId);

                                    //查看合成藏品后藏品的库存
                                    updInven(nftId);

                                    //修改原材料的状态和销毁藏品
                                    delNft(nftIdList,owner,mbId);

                                    //发行藏品
                                    chainAcco(nftId, owner,certId,mbId);

                                    //添加藏品证书
                                    addDcNftCert(certId,nftId,mbId);

                                    //返回藏品证书
                                    certVo = dcNtfCert(certId,nftId);

                                }
                            } else {
                                //发行库存量总和是否为0
                                throw new CommonException("活动的所有藏品已经合成完");
                            }
                        }
                    }
                }
                //判断用户是否符合门槛信息
                Boolean flage = false;
                for (int u = 0; u < equayList.size(); u++) {
                    Boolean b = equayList.get(u);
                    flage = flage || b;
                }
                //不符合输出
                if (!flage) {
                    throw new CommonException("不符合该活动的门槛信息，不能参与活动");
                }
            }
        } else {
            throw new CommonException("拥有的原材料不足，不能参与活动");
        }
        return certVo;
    }

    /**
     * 藏品总数
     *
     * @param nftId 藏品标识
     * @param synId 活动标识
     * @return
     */
    @Override
    public Integer sumInven(String nftId, String synId) {
        return opSynActInfoMapper.sumInven(nftId, null);
    }

    /**
     * 查看会员是否拥有该藏品
     *
     * @param mbId  会员Id
     * @param nftId 藏品Id
     * @return
     */
    @Override
    public List<OpSynCertListVo> getSynRaw(String mbId, String nftId) {
        List<OpSynCertListVo> synRaw = opSynActInfoMapper.getSynRaw(mbId, nftId);
        return synRaw;
    }


    /**
     * 修改合成活动后藏品的库存量
     */
    private int updSunInven(String nftId,int inven){
        LambdaUpdateWrapper<OpSynActRules> opSynActRulesUpdat = new LambdaUpdateWrapper<>();
        // 设置更新条件：根据用户ID查找记录
        opSynActRulesUpdat.eq(OpSynActRules::getNftId, nftId);
        // 设置要更新的字段和新值：例如更新用户状态
        opSynActRulesUpdat.set(OpSynActRules::getInventory, inven);
        int update = opSynActRulesMapper.update(null, opSynActRulesUpdat);
        return update;
    }

    /**
     * 修改合成藏品后藏品的库存
     */
    private int updInven(String nftId){
        QueryWrapper<DcNftInfo> dcNftInfoQueryWrapper = new QueryWrapper<>();
        dcNftInfoQueryWrapper.lambda().eq(DcNftInfo::getId, nftId);
        DcNftInfo dcNftInfo = dcNftInfoMapper.selectOne(dcNftInfoQueryWrapper);
        Integer inventory1 = dcNftInfo.getInventory();
        Integer integer = inventory1 - 1;
        //修改合成藏品后藏品的库存
        UpdateWrapper<DcNftInfo> dcNftInfoQuery = new UpdateWrapper<>();
        // 设置更新条件：根据用户ID查找记录
        dcNftInfoQuery.eq("id", nftId);
        // 设置要更新的字段和新值：例如更新用户状态
        dcNftInfoQuery.set("inventory", integer);
        int update = dcNftInfoMapper.update(null, dcNftInfoQuery);
        return update;
    }

    /**
     * 返回藏品证书
     */
    private DcNftCertVo dcNtfCert(String certId,String nftId){
        DcNftInfoVo dcNftInfoVo = dcNftInfoMapper.selectVoById(nftId);
        String name = dcNftInfoVo.getName();
        String cover = dcNftInfoVo.getCover();

        QueryWrapper<DcNftCert> dcNtfCertQuery = new QueryWrapper<>();
        dcNtfCertQuery.lambda().eq(DcNftCert::getId, certId);
        DcNftCertVo dcNftCertVo = dcNftCertMapper.selectVoOne(dcNtfCertQuery);
        dcNftCertVo.setNftName(name);
        dcNftCertVo.setNftCover(cover);
        return dcNftCertVo;
    }


    /**
     * 添加合成记录
     */
    private int addSynRecordLog(String mbId,String certId,String synId){
        OpSynRecordLog synRecordLog = new OpSynRecordLog();
        //合成记录Id
        String logId = IdUtil.getSnowflakeNextIdStr();
        synRecordLog.setId(logId);
        //会员标识
        synRecordLog.setMbId(mbId);
        //藏品证书标识
        synRecordLog.setNftCertId(certId);
        //合成状态
        synRecordLog.setStatus(SyndropEnum.SYNTHESIS_SUCCESSFUL.getValue());
        //合成时间
        synRecordLog.setSynTime(new Date());
        //合成活动信息标识
        synRecordLog.setSynActId(synId);
        //添加合成记录
        int insert = opSynRecordLogMapper.insert(synRecordLog);
        return insert;
    }

    /**
     * 添加流转记录
     */
    private int addDcFlowLog(String certId,String mbId){
        //流转Id
        String flowId = IdUtil.getSnowflakeNextIdStr();
        //封装藏品流转记录
        DcFlowLog dcFlowLog = new DcFlowLog();
        dcFlowLog.setId(flowId);
        //藏品证书ID
        dcFlowLog.setCertId(certId);
        //会员ID
        dcFlowLog.setMbId(mbId);
        //流转方式
        dcFlowLog.setCirculation(SyndropEnum.SYNTHESIS.getValue());
        //流转时间
        dcFlowLog.setFlowTime(new Date());
        int insert = dcFlowLogMapper.insert(dcFlowLog);
        return insert;
    }

    /**
     * 添加藏品证书
     */
    private int addDcNftCert(String certId,String nftId,String mbId){
        //藏品证书的编号
        //Integer code = NftCodeUtil.getRightPop(nftId);
        //封装藏品证书信息
        DcNftCert dcNftCert = new DcNftCert();
        dcNftCert.setId(certId);
        //藏品标识
        dcNftCert.setNftId(nftId);
        //会员标识
        dcNftCert.setMbId(mbId);
        //藏品编号
        dcNftCert.setCode(200);
        //发行时间
        dcNftCert.setReleaseTime(new Date());
        //发证单位
        dcNftCert.setUnit("shdgf");
        //合约地址
        //dcNftCert.setContractAddr("shjdfgcvbhg");
        //链上地址
        //dcNftCert.setChainAddr(classId);
        //证书状态
        dcNftCert.setStatus(SyndropEnum.HOIDING.getValue());
        //证书时间
        dcNftCert.setReleaseTime(new Date());
        int insert = dcNftCertMapper.insert(dcNftCert);
        return insert;
    }

    /**
     * 销毁和修改原材料的状态
     */
    private String delNft(List<String> nftIdList,String owner,String mbId){
        String operationId = null;
        for (int e = 0; e < nftIdList.size(); e++) {
            String nft = nftIdList.get(e);
            UpdateWrapper<DcNftCert> dcNtfCertUpdateWrapper = new UpdateWrapper<>();
            // 设置更新条件：根据用户ID查找记录
            dcNtfCertUpdateWrapper.eq("nft_id", nft);
            // 设置要更新的字段和新值：例如更新用户状态
            dcNtfCertUpdateWrapper.set("status", 3);
            dcNtfCertUpdateWrapper.set("disappear_time", new Date());
            dcNftCertMapper.update(null, dcNtfCertUpdateWrapper);
            //链上销毁
            //NFT ID
            QueryWrapper<DcNftCert> dcNftCertQueryWrapper = new QueryWrapper<>();
            dcNftCertQueryWrapper.lambda().eq(DcNftCert::getId,nft);
            DcNftCertVo dcNftCertVo = dcNftCertMapper.selectVoOne(dcNftCertQueryWrapper);
            String nftIdDev = dcNftCertVo.getChainAddr();
            String id = dcNftCertVo.getId();
            String nftId = dcNftCertVo.getNftId();

            //类别 ID
            QueryWrapper<DcNftInfo> dcNftInfoQueryWrappe = new QueryWrapper<>();
            dcNftInfoQueryWrappe.lambda().eq(DcNftInfo::getId,nftId);
            DcNftInfo dcNftInf = dcNftInfoMapper.selectOne(dcNftInfoQueryWrappe);
            String classId = dcNftInf.getContract();

            //销毁
            operationId = devBlockChainApi.disNft(classId,owner,nftIdDev);
            //销毁状态查看
            TradingResultsInfo tradingResultsInfo = devBlockChainApi.queryTranRecords(operationId);
            Integer status = tradingResultsInfo.getData().getStatus();
            //日志表
            String idStr = IdUtil.getSnowflakeNextIdStr();
            ChainOptLogInfo chainOptLogInfo = new ChainOptLogInfo();
            chainOptLogInfo.setId(idStr);
            chainOptLogInfo.setDcOptType(ChainLogEnum.BUSINESS_SYN.getValue());
            chainOptLogInfo.setChainOptType(ChainLogEnum.CHAIN_DESTROYED_NFT.getValue());
            chainOptLogInfo.setStatus(status);
            chainOptLogInfo.setObjId(nft);
            chainOptLogInfo.setOperationId(operationId);
            chainOptLogInfo.setOptTime(new Date());
            //获取描述
            String destroyed = LogDescription.destroyed(mbId,id);
            chainOptLogInfo.setOptDesc(destroyed);
            chainOptLogInfo.setUserId(mbId);
        }
        return operationId;
    }


    /**
     * 上链(发行藏品)
     */
    private String chainAcco(String nft,String owner,String certId,String mbId){
        ChainAccountInfo chainAccountInfo = new ChainAccountInfo();
        //获取所需要的信息
        DcNftInfoVo dcNftInfoVo = dcNftInfoMapper.selectVoById(nft);
        //名称
        chainAccountInfo.setName(dcNftInfoVo.getName());
        //公网路径
        chainAccountInfo.setUri(dcNftInfoVo.getCover());
        //nft类别链上标识
        chainAccountInfo.setClassId(dcNftInfoVo.getContract());
        //类型
        chainAccountInfo.setType(Integer.valueOf(dcNftInfoVo.getType()));
        //发售时间
        chainAccountInfo.setSaleTime(dcNftInfoVo.getSaleTime());
        //接收者链上标识
        chainAccountInfo.setNativeAddress(owner);
        //调用发行接口
        String operationId = devBlockChainApi.publishNft(chainAccountInfo);
        TradingResultsInfo tradingResultsInfo = devBlockChainApi.queryTranRecords(operationId);
        Integer status = tradingResultsInfo.getData().getStatus();
        //日志表
        String idStr = IdUtil.getSnowflakeNextIdStr();
        ChainOptLogInfo chainOptLogInfo = new ChainOptLogInfo();
        chainOptLogInfo.setId(idStr);
        chainOptLogInfo.setDcOptType(ChainLogEnum.BUSINESS_SYN.getValue());
        chainOptLogInfo.setChainOptType(ChainLogEnum.CHAIN_PUBLISH_NFT.getValue());
        chainOptLogInfo.setStatus(status);
        chainOptLogInfo.setObjId(nft);
        chainOptLogInfo.setOperationId(operationId);
        chainOptLogInfo.setOptTime(new Date());
        //获取描述
        String destroyed = LogDescription.issuance(mbId,certId,ChainLogEnum.BUSINESS_SYN.getName());
        chainOptLogInfo.setOptDesc(destroyed);
        chainOptLogInfo.setUserId(mbId);
        return operationId;
    }


    /**
     * 添加验证库存
     */
    private Boolean checkStockAdd(String nftId, Integer num) {
        return checkStockUpdate(nftId, null, num);
    }

    /**
     * 修改验证库存
     */
    private Boolean checkStockUpdate(String nftId, String synId, Integer num) {
        //条件构造器
        QueryWrapper<DcNftInfo> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<DcNftInfo> lambda = wrapper.lambda();
        lambda.eq(DcNftInfo::getId, nftId);
        //查询藏品的库存
        DcNftInfo dcNftInfo = dcNftInfoMapper.selectOne(wrapper);
        Integer nftStock = Integer.valueOf(dcNftInfo.getInventory());
        //查询活动中藏品的库存
        Integer synStock = opSynActInfoMapper.sumInven(nftId, synId);
        if (synStock == null) {
            synStock = 0;
        }
        //可用库存
        Integer availableStock = nftStock - synStock;
        if (num > availableStock) {
            return false;
        }
        return true;
    }

    @Override
    public Page<DcNftCerVo> queryNftCert(Integer pageNo, Integer pageSize, DcCertQuery dcCertQuery) {
        Page<DcNftCerVo> dcNftCertVoPage = new Page<>(pageNo, pageSize);
        //2.查询藏品证书信息
        List<DcNftCerVo> dcNftCertVos = opSynActInfoMapper.queryCer(dcNftCertVoPage, dcCertQuery.getMbId(), dcCertQuery.getStatus());
        dcNftCertVoPage.setRecords(dcNftCertVos);
        return dcNftCertVoPage;
    }


    @Override
    public List<AutNftInfoVo> getAutNft(String id, String mbId) {
        List<AutNftInfoVo> autInfo = opSynActInfoMapper.getAutInfo(id, mbId);
        return autInfo;
    }

}
